package com.sfl.api_backend.Filters;

import com.alibaba.fastjson2.JSON;
import com.sfl.api_backend.entity.SecurityUser;
import com.sfl.api_backend.entity.Users;
import com.sfl.api_backend.utils.Jwt.JwtUtil;
import com.sfl.api_backend.utils.Redis.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author szc
 * @create 2023/2/3 12:14
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Resource
    private RedisUtil redisUtil;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // get token from request
        String token = request.getHeader("token");

        Users users = null;

        // validate token
        if(StringUtils.isEmpty(token)){
            // throw exception
            filterChain.doFilter(request, response);
            return;
        }
        try {
            String userJson = JwtUtil.parseJWT(token).getSubject();
            users = JSON.parseObject(userJson, Users.class);
        } catch (Exception e) {
            throw new RuntimeException("token非法");
        }
        // get user info from token
        String redisKey = "SignInUser:" + users.getUserId();
        String redisUserJson = (String) redisUtil.get(redisKey);
        if(StringUtils.isEmpty(redisUserJson)){
            throw new RuntimeException("token已过期");
        }
        Users redisUser = JSON.parseObject(redisUserJson, Users.class);
        SecurityUser securityUser = new SecurityUser(redisUser);
        // save user info to security context
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities()));
        // continue
        filterChain.doFilter(request, response);
    }
}
